<template>
  <div class="element-selector-container">
    <!-- 选择器模式遮罩层 -->
    <div
        v-if="isSelecting"
        class="selector-overlay"
        @mousemove="updateSelectorPosition"
        @click="handleElementSelection"
    >
      <div
          class="selector-cursor"
          :style="cursorStyle"
      ></div>
      <div class="selector-hint">
        点击选择页面元素 (ESC取消)
      </div>
    </div>

    <!-- 主界面 -->
    <div class="selector-controls">
      <button
          class="selector-button primary"
          @click="startSelection"
          :disabled="isSelecting"
      >
        <i class="icon-select"></i> {{ isSelecting ? '选择中...' : '开始选择元素' }}
      </button>

      <button
          class="selector-button"
          @click="clearSelection"
          :disabled="selectedElements.length === 0"
      >
        <i class="icon-clear"></i> 清空选择
      </button>
    </div>

    <!-- 已选择元素列表 -->
    <div class="selected-elements" v-if="selectedElements.length > 0">
      <div class="elements-header">
        <span class="elements-count">已选择 {{ selectedElements.length }} 个元素</span>
        <div class="elements-actions">
          <button
              class="action-button"
              @click="highlightAll"
              :disabled="highlightedCount === selectedElements.length"
          >
            <i class="icon-highlight"></i> 高亮全部
          </button>
          <button
              class="action-button"
              @click="unhighlightAll"
              :disabled="highlightedCount === 0"
          >
            <i class="icon-unhighlight"></i> 取消高亮
          </button>
        </div>
      </div>

      <div class="elements-list">
        <div
            v-for="(element, index) in selectedElements"
            :key="element.id"
            class="element-item"
            :class="{ highlighted: isHighlighted(element.node) }"
            @mouseenter="highlightElement(element.node, true)"
            @mouseleave="unhighlightElement(element.node)"
        >
          <div class="element-info">
            <div class="element-tag">{{ element.node.tagName.toLowerCase() }}</div>
            <div class="element-content" :title="element.content">
              {{ element.content }}
            </div>
            <div class="element-path" :title="element.path">
              {{ element.path }}
            </div>
          </div>

          <div class="element-actions">
            <button
                class="action-button small"
                @click="scrollToElement(element.node)"
                title="滚动到元素"
            >
              <i class="icon-scroll"></i>
            </button>
            <button
                class="action-button small"
                @click="inspectElement(element.node)"
                title="查看详情"
            >
              <i class="icon-inspect"></i>
            </button>
            <button
                class="action-button small danger"
                @click="removeElement(index)"
                title="移除选择"
            >
              <i class="icon-remove"></i>
            </button>
          </div>
        </div>
      </div>
    </div>

    <div class="no-elements" v-else>
      <div class="no-elements-message">
        没有已选择的元素，点击"开始选择元素"按钮选择页面元素
      </div>
    </div>
  </div>
</template>
<script>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'

export default {
  props: {
    highlightColor: {
      type: String,
      default: '#ff1f71'
    }
  },

  emits: ['inspect', 'scroll-to'],

  setup(props, { emit }) {
    // 选择器状态
    const isSelecting = ref(false)
    const cursorPosition = ref({ x: 0, y: 0 })
    const selectedElements = ref([])

    // 生成唯一ID
    const generateId = (() => {
      let counter = 0
      return () => `element-${++counter}`
    })()

    // 计算属性
    const cursorStyle = computed(() => ({
      left: `${cursorPosition.value.x}px`,
      top: `${cursorPosition.value.y}px`
    }))

    const highlightedCount = computed(() => {
      return selectedElements.value.filter(el =>
          el.node.classList.contains('selector-highlighted')
      ).length
    })

    // 元素选择方法
    const startSelection = () => {
      if (isSelecting.value) return

      isSelecting.value = true
      document.body.style.cursor = 'crosshair'
      document.addEventListener('keydown', handleEscapeKey)
    }

    const stopSelection = () => {
      isSelecting.value = false
      document.body.style.cursor = ''
      document.removeEventListener('keydown', handleEscapeKey)
    }

    const handleEscapeKey = (e) => {
      if (e.key === 'Escape') {
        stopSelection()
      }
    }

    const updateSelectorPosition = (e) => {
      cursorPosition.value = { x: e.clientX, y: e.clientY }
    }

    const handleElementSelection = (e) => {
      e.preventDefault()
      e.stopPropagation()

      // 忽略body和html元素
      if (e.target === document.body || e.target === document.documentElement) {
        return
      }

      // 检查是否已选择
      if (selectedElements.value.some(el => el.node === e.target)) {
        console.log('元素已选择')
        return
      }

      // 添加新元素
      addSelectedElement(e.target)
      stopSelection()
    }

    const addSelectedElement = (element) => {
      selectedElements.value.push({
        id: generateId(),
        node: element,
        content: getElementContent(element),
        path: getElementPath(element)
      })
    }

    // 元素操作方法
    const highlightElement = (element, isTemporary = false) => {
      if (!element || !element.style) return

      element.classList.add('selector-highlighted')
      element.style.setProperty('--highlight-color', props.highlightColor)

      if (!isTemporary) {
        element.dataset.selectorPermanentHighlight = 'true'
      }
    }

    const unhighlightElement = (element) => {
      if (!element || !element.style) return

      if (!element.dataset.selectorPermanentHighlight) {
        element.classList.remove('selector-highlighted')
      }
    }

    const isHighlighted = (element) => {
      return element.classList?.contains('selector-highlighted')
    }

    const highlightAll = () => {
      selectedElements.value.forEach(item => {
        highlightElement(item.node)
        item.node.dataset.selectorPermanentHighlight = 'true'
      })
    }

    const unhighlightAll = () => {
      selectedElements.value.forEach(item => {
        unhighlightElement(item.node)
        delete item.node.dataset.selectorPermanentHighlight
      })
    }

    const scrollToElement = (element) => {
      if (element && element.scrollIntoView) {
        element.scrollIntoView({
          behavior: 'smooth',
          block: 'center'
        })
        emit('scroll-to', element)
      }
    }

    const inspectElement = (element) => {
      emit('inspect', element)
    }

    const removeElement = (index) => {
      if (index >= 0 && index < selectedElements.value.length) {
        const [removed] = selectedElements.value.splice(index, 1)
        unhighlightElement(removed.node)
      }
    }

    const clearSelection = () => {
      unhighlightAll()
      selectedElements.value = []
    }

    // 辅助函数
    const getElementContent = (element) => {
      const text = element.textContent?.trim() || ''
      if (text) return text.length > 50 ? text.substring(0, 50) + '...' : text

      if (element.id) return `#${element.id}`
      if (element.className) return `.${element.className}`

      return element.tagName.toLowerCase()
    }

    const getElementPath = (element) => {
      if (!element || !element.tagName) return ''

      const path = []
      let current = element

      while (current && current.tagName && current.tagName.toLowerCase() !== 'html') {
        let selector = current.tagName.toLowerCase()

        if (current.id) {
          selector += `#${current.id}`
          path.unshift(selector)
          break
        } else {
          let sibling = current
          let nth = 1

          while (sibling.previousElementSibling) {
            sibling = sibling.previousElementSibling
            nth++
          }

          if (current.className) {
            selector += `.${current.className.split(' ').join('.')}`
          }

          selector += `:nth-child(${nth})`
          path.unshift(selector)
        }

        current = current.parentNode
      }

      return path.join(' > ')
    }

    // 生命周期钩子
    onBeforeUnmount(() => {
      stopSelection()
      clearSelection()
    })

    return {
      isSelecting,
      cursorPosition,
      selectedElements,
      cursorStyle,
      highlightedCount,
      startSelection,
      clearSelection,
      updateSelectorPosition,
      handleElementSelection,
      highlightElement,
      unhighlightElement,
      isHighlighted,
      highlightAll,
      unhighlightAll,
      scrollToElement,
      inspectElement,
      removeElement,
      getElementContent,
      getElementPath
    }
  }
}
</script>
<style scoped>
.element-selector-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 15px;
  background: rgba(10, 20, 30, 0.85);
  border-radius: 12px;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  color: rgba(255, 255, 255, 0.9);
}

/* 选择器遮罩层 */
.selector-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 9998;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: crosshair;
}

.selector-cursor {
  position: absolute;
  width: 40px;
  height: 40px;
  border: 2px solid var(--highlight-color, #ff1f71);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: pulse 1.5s infinite;
  z-index: 9999;
}

.selector-hint {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px 20px;
  border-radius: 20px;
  font-size: 14px;
  z-index: 9999;
}

@keyframes pulse {
  0% { transform: translate(-50%, -50%) scale(1); opacity: 0.7; }
  50% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 0.7; }
}

/* 控制按钮 */
.selector-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.selector-button {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-family: inherit;
  font-weight: bold;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.9);
}

.selector-button:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
}

.selector-button.primary {
  background: linear-gradient(135deg, #00ff87 0%, #60efff 100%);
  color: #111;
}

.selector-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 已选择元素列表 */
.selected-elements {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
}

.elements-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.elements-count {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.7);
}

.elements-actions {
  display: flex;
  gap: 8px;
}

.elements-list {
  flex: 1;
  overflow-y: auto;
  padding: 5px;
}

.element-item {
  padding: 10px;
  margin: 5px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 4px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.element-item:hover {
  background: rgba(255, 255, 255, 0.1);
}

.element-item.highlighted {
  background: rgba(255, 31, 113, 0.1);
}

.element-info {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  overflow: hidden;
}

.element-tag {
  font-size: 12px;
  background: rgba(0, 255, 135, 0.2);
  color: #00ff87;
  padding: 2px 6px;
  border-radius: 4px;
  white-space: nowrap;
}

.element-content {
  flex: 1;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.element-path {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.7);
  font-family: 'Fira Code', monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}

.element-actions {
  display: flex;
  gap: 5px;
}

/* 动作按钮 */
.action-button {
  padding: 6px 12px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.action-button:hover {
  background: rgba(255, 255, 255, 0.1);
}

.action-button.danger {
  color: #ff5555;
  border-color: rgba(255, 85, 85, 0.3);
}

.action-button.danger:hover {
  background: rgba(255, 85, 85, 0.1);
}

.action-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-button.small {
  padding: 4px 8px;
  font-size: 11px;
}

/* 无元素提示 */
.no-elements {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, 0.7);
  font-size: 14px;
  padding: 20px;
  text-align: center;
}

/* 图标样式 */
.icon-select,
.icon-clear,
.icon-highlight,
.icon-unhighlight,
.icon-scroll,
.icon-inspect,
.icon-remove {
  display: inline-block;
  width: 14px;
  height: 14px;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.icon-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23111'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122' /%3E%3C/svg%3E");
}

.icon-clear {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16' /%3E%3C/svg%3E");
}

.icon-highlight {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z' /%3E%3C/svg%3E");
}

.icon-unhighlight {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21' /%3E%3C/svg%3E");
}

.icon-scroll {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ffffff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 14l-7 7m0 0l-7-7m7 7V3' /%3E%3C/svg%3E");
}

.icon-inspect {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2300bfff'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 12a3 3 0 11-6 0 3 3 0 016 0z' /%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z' /%3E%3C/svg%3E");
}

.icon-remove {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ff5555'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' /%3E%3C/svg%3E");
}

/* 滚动条样式 */
.elements-list::-webkit-scrollbar {
  width: 8px;
}

.elements-list::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
}

.elements-list::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 4px;
}

.elements-list::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.4);
}

/* 全局高亮样式 */
:global(.selector-highlighted) {
  outline: 2px solid var(--highlight-color, #ff1f71) !important;
  outline-offset: 2px !important;
  box-shadow: 0 0 10px var(--highlight-color, #ff1f71) !important;
  animation: highlight-pulse 1s infinite;
}

@keyframes highlight-pulse {
  0% { box-shadow: 0 0 5px var(--highlight-color, #ff1f71); }
  50% { box-shadow: 0 0 20px var(--highlight-color, #ff1f71); }
  100% { box-shadow: 0 0 5px var(--highlight-color, #ff1f71); }
}
</style>
